In this tutorial, we will learn how to generate REST API documentation using theb SpringDoc OpenAPI library in Spring Boot 3 Applications.
Check out my 10+ Udemy courses to learn Spring boot, Microservices, and Full stack development: https://www.javaguides.net/p/my-udemy-courses-ramesh-fadatare.html.
The springdoc-openapi java library helps to automate the generation of API documentation using spring boot projects.
The springdoc-openapi java library provides integration between spring-boot and swagger-UI.
The springdoc-openapi java library automatically generates documentation in JSON/YAML and HTML format APIs.
This library supports:
This is a community-based project, not maintained by the Spring Framework Contributors.
We are going to generate REST API documentation for a user management project developed using below tutorial:
Spring Boot 3, MySQL, Spring Data JPA, Hibernate CRUD REST API Tutorial [2024]
Before proceeding with this tutorial, make sure that you set up the Spring Boot project with CRUD REST APIs.
The springdoc-openapi dependency provides integration between spring-boot and swagger-UI.
Let's add the below dependency to the Spring Boot 3 Maven project:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.4</version>
</dependency>
Next, run the Spring boot application and access the Swagger UI in the browser using the below URL: http://localhost:8080/swagger-ui/index.html
There are two ways to define API information. You can define API information programmatically or using Annotations. In this tutorial, we will define the general API information using annotations.
Let's open the main entry point class and add the following code:
package net.javaguides.springboot;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@OpenAPIDefinition(
info = @Info(
title = "Spring Boot REST API Documentation",
description = "Spring Boot REST API Documentation",
version = "v1.0",
contact = @Contact(
name = "Ramesh",
email = "javaguides.net@gmail.com",
url = "https://www.javaguides.net"
),
license = @License(
name = "Apache 2.0",
url = "https://www.javaguides.net/license"
)
),
externalDocs = @ExternalDocumentation(
description = "Spring Boot User Management Documentation",
url = "https://www.javaguides.net/user_management.html"
)
)
public class SpringbootRestfulWebservicesApplication {
@Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}
public static void main(String[] args) {
SpringApplication.run(SpringbootRestfulWebservicesApplication.class, args);
}
}
Note that we have used Swagger annotations to define API information:
@OpenAPIDefinition(
info = @Info(
title = "Spring Boot REST API Documentation",
description = "Spring Boot REST API Documentation",
version = "v1.0",
contact = @Contact(
name = "Ramesh",
email = "javaguides.net@gmail.com",
url = "https://www.javaguides.net"
),
license = @License(
name = "Apache 2.0",
url = "https://www.javaguides.net/license"
)
),
externalDocs = @ExternalDocumentation(
description = "Spring Boot User Management Documentation",
url = "https://www.javaguides.net/user_management.html"
)
)
Next, we can customize the REST API documentation using annotations like we can provide more information about the Resource and REST APIs.
Let's open UserController and let's use annotations to add more information about REST APIs in the documentation.
package net.javaguides.springboot.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.entity.User;
import net.javaguides.springboot.exception.ErrorDetails;
import net.javaguides.springboot.exception.ResourceNotFoundException;
import net.javaguides.springboot.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import java.time.LocalDateTime;
import java.util.List;
@Tag(
name = "CRUD REST APIs for User Resource",
description = "CRUD REST APIs - Create User, Update User, Get User, Get All Users, Delete User"
)
@RestController
@AllArgsConstructor
@RequestMapping("api/users")
public class UserController {
private UserService userService;
@Operation(
summary = "Create User REST API",
description = "Create User REST API is used to save user in a database"
)
@ApiResponse(
responseCode = "201",
description = "HTTP Status 201 CREATED"
)
// build create User REST API
@PostMapping
public ResponseEntity< UserDto> createUser(@Valid @RequestBody UserDto user){
UserDto savedUser = userService.createUser(user);
return new ResponseEntity< >(savedUser, HttpStatus.CREATED);
}
@Operation(
summary = "Get User By ID REST API",
description = "Get User By ID REST API is used to get a single user from the database"
)
@ApiResponse(
responseCode = "200",
description = "HTTP Status 200 SUCCESS"
)
// build get user by id REST API
// http://localhost:8080/api/users/1
@GetMapping("{id}")
public ResponseEntity< UserDto> getUserById(@PathVariable("id") Long userId){
UserDto user = userService.getUserById(userId);
return new ResponseEntity< >(user, HttpStatus.OK);
}
@Operation(
summary = "Get All Users REST API",
description = "Get All Users REST API is used to get a all the users from the database"
)
@ApiResponse(
responseCode = "200",
description = "HTTP Status 200 SUCCESS"
)
// Build Get All Users REST API
// http://localhost:8080/api/users
@GetMapping
public ResponseEntity< List< UserDto>> getAllUsers(){
List< UserDto> users = userService.getAllUsers();
return new ResponseEntity< >(users, HttpStatus.OK);
}
@Operation(
summary = "Update User REST API",
description = "Update User REST API is used to update a particular user in the database"
)
@ApiResponse(
responseCode = "200",
description = "HTTP Status 200 SUCCESS"
)
// Build Update User REST API
@PutMapping("{id}")
// http://localhost:8080/api/users/1
public ResponseEntity< UserDto> updateUser(@PathVariable("id") Long userId,
@RequestBody @Valid UserDto user){
user.setId(userId);
UserDto updatedUser = userService.updateUser(user);
return new ResponseEntity< >(updatedUser, HttpStatus.OK);
}
@Operation(
summary = "Delete User REST API",
description = "Delete User REST API is used to delete a particular user from the database"
)
@ApiResponse(
responseCode = "200",
description = "HTTP Status 200 SUCCESS"
)
// Build Delete User REST API
@DeleteMapping("{id}")
public ResponseEntity< String> deleteUser(@PathVariable("id") Long userId){
userService.deleteUser(userId);
return new ResponseEntity< >("User successfully deleted!", HttpStatus.OK);
}
// @ExceptionHandler(ResourceNotFoundException.class)
// public ResponseEntity< ErrorDetails> handleResourceNotFoundException(ResourceNotFoundException exception,
// WebRequest webRequest){
//
// ErrorDetails errorDetails = new ErrorDetails(
// LocalDateTime.now(),
// exception.getMessage(),
// webRequest.getDescription(false),
// "USER_NOT_FOUND"
// );
//
// return new ResponseEntity< >(errorDetails, HttpStatus.NOT_FOUND);
// }
}
Note that we have used 3 annotations to customize the RESt API documentation.
@Tag annotation is used to provide resource information:
@Tag(
name = "CRUD REST APIs for User Resource",
description = "CRUD REST APIs - Create User, Update User, Get User, Get All Users, Delete User"
)
@Operation and @ApiResponse annotations to provide REST API information:
@Operation(
summary = "Create User REST API",
description = "Create User REST API is used to save user in a database"
)
@ApiResponse(
responseCode = "201",
description = "HTTP Status 201 CREATED"
)
Next, we can also customize the Model classes in Swagger documentation using annotations.
Let's open UserDto class and add @Schema annotation to provide the model and its attributes information:
package net.javaguides.springboot.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Schema(
description = "UserDto Model Information"
)
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
private Long id;
@Schema(
description = "User First Name"
)
// User first name should not be null or empty
@NotEmpty(message = "User first name should not be null or empty")
private String firstName;
@Schema(
description = "User Last Name"
)
// User last name should not be null or empty
@NotEmpty(message = "User last name should not be null or empty")
private String lastName;
@Schema(
description = "User Email Address"
)
// User email should not be null or empty
// Email address should be valid
@NotEmpty(message = "User email should not be null or empty")
@Email(message = "Email address should be valid")
private String email;
}
Finally, let's run the Spring boot application and access the REST API documentation using below swagger URL:
http://localhost:8080/swagger-ui/index.html
Next, use the below URL to generate API documentation in JSON format.
http://localhost:8080/v3/api-docsIn this tutorial, we learned how to generate REST API documentation using the SpringDoc OpenAPI library in Spring Boot 3 Applications.